home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / chasm.bas (.txt) < prev    next >
Encoding:
GW-BASIC  |  1988-11-09  |  32.2 KB  |  1,186 lines

  1. 10000  '===========================
  2. 10010  'CHASM Version 2.13
  3. 10020  'Begun 6/15/82 by D. Whitman
  4. 10030  '===========================
  5. 10040  DEFINT A-Z
  6. 10050  MAXOBJ = 74: DIM OBJ(74)
  7. 10060  MAXSTK = 10: DIM PROCTYPE(10): STKTOP = 0
  8. 10070  NUMOP = 227
  9. 10080  DIM OPCODE$(227),OPVAL(227),SRCTYPE(227),DSTTYPE(227),OFLAG(227)
  10. 10090  PREDEF = 29: MAXSYM = 200
  11. 10100  DIM SYM$(200),VAL1(200),VAL2(29),SYMTYPE(200)
  12. 10110  '
  13. 10120  'main program
  14. 10130   GOSUB 50000  'init
  15. 10140   CHAIN MERGE "nul",10150,ALL,DELETE 50000-51770 'kill init code
  16. 10150   GOSUB 19710  'finish init
  17. 10160   GOSUB 10200  'pass 1: build sym table
  18. 10170   GOSUB 10440  'pass 2: obj code & listing
  19. 10180   GOSUB 19150  'clean up
  20. 10190   GOSUB 19510  'exit
  21. 10200  '===================
  22. 10210  'PASSONE
  23. 10220  'Builds symbol table
  24. 10230  '===================
  25. 10240  PASS = 1
  26. 10250  OPEN O$ AS #3 LEN=1: FIELD #3,1 AS BYTE$
  27. 10260  LOCTR = 256
  28. 10270  LINENUM = 0
  29. 10280  BASCODE = FALSE
  30. 10290  WHILE NOT EOF(1)
  31. 10300   'abort?
  32. 10310    GOSUB 20010
  33. 10320   'get line, init
  34. 10330    GOSUB 10660
  35. 10340   'parse
  36. 10350    GOSUB 10830
  37. 10360   'label? add to table
  38. 10370    IF LABEL$ <> "" THEN GOSUB 11640
  39. 10380   'op? decode, update loctr
  40. 10390    IF OP$ <> "" THEN GOSUB 12420
  41. 10400   'report
  42. 10410    GOSUB 19580
  43. 10420   WEND
  44. 10430  RETURN
  45. 10440  '===================
  46. 10450  'PASSTWO
  47. 10460  'Generates obj code & listing
  48. 10470  '===================
  49. 10480  GOSUB 18870  'pass2_init
  50. 10490  WHILE NOT EOF(1)
  51. 10500   'abort?
  52. 10510    GOSUB 20010
  53. 10520   'get line, init
  54. 10530    GOSUB 10660
  55. 10540   'parse
  56. 10550    GOSUB 10830
  57. 10560   'phase?
  58. 10570    IF LABEL$ <> "" THEN GOSUB 11880
  59. 10580   'update loctr, gen. obj. code
  60. 10590    IF OP$ <> "" THEN GOSUB 12420
  61. 10600   'output
  62. 10610    GOSUB 18270
  63. 10620   'report
  64. 10630    GOSUB 19580
  65. 10640   WEND
  66. 10650  RETURN
  67. 10660  '===================
  68. 10670  'GETLINE
  69. 10680  'Get line, expand tabs & set up
  70. 10690  '===================
  71. 10700  LINE INPUT#1, INPLINE$
  72. 10710  GOSUB 10770  'tabs
  73. 10720  LINENUM = LINENUM + 1
  74. 10730  NEEDOFFSET = NONE: DSFLAG = FALSE: ERRORFLAG = FALSE
  75. 10740  OBJLEN = 0
  76. 10750  RETURN
  77. 10760  'tabs
  78. 10770  I = INSTR(INPLINE$,CHR$(9))
  79. 10780  WHILE I <> 0
  80. 10790   INPLINE$ = LEFT$(INPLINE$,I-1)+SPACE$(8-((I-1)MOD 8))+MID$(INPLINE$,I+1)
  81. 10800   I = INSTR(INPLINE$,CHR$(9))
  82. 10810   WEND
  83. 10820  RETURN
  84. 10830  '=================
  85. 10840  'PARSE
  86. 10850  'Parses input line
  87. 10860  '=================
  88. 10870  LINEPTR = 1: LINEPTR2 = 1
  89. 10880  LABEL$ = "": OP$ = "": SOURCE$ = "": DEST$ = ""
  90. 10890  'mark end of code
  91. 10900   ENDPTR = INSTR(INPLINE$,";") - 1
  92. 10910   IF ENDPTR = -1 THEN ENDPTR = LEN(INPLINE$)
  93. 10920  'no code? (exit)
  94. 10930   IF ENDPTR = 0 THEN 11180
  95. 10940  'too long?
  96. 10950   IF ENDPTR <= 80 THEN 10980
  97. 10960      IF PASS = 2 THEN MSG$ = "Source line truncated": GOSUB 19030
  98. 10970      ENDPTR = 80
  99. 10980  'all caps
  100. 10990   GOSUB 11200
  101. 11000  'label?
  102. 11010   IF INSTR(DELIM$,LEFT$(INPLINE$,1))  THEN 11040
  103. 11020     GOSUB 11320  'getfield
  104. 11030     LABEL$ = FLD$
  105. 11040  'opcode
  106. 11050   GOSUB 11320  'getfield
  107. 11060   IF NOT FOUND THEN 11180
  108. 11070   OP$ = FLD$
  109. 11080  'save ptr to start of opds
  110. 11090   OPDPTR = LINEPTR
  111. 11100  'dest?
  112. 11110   GOSUB 11320  'getfield
  113. 11120   IF NOT FOUND THEN 11180
  114. 11130   DEST$ = FLD$
  115. 11140  'src?
  116. 11150   GOSUB 11320  'getfield
  117. 11160   IF NOT FOUND THEN 11180
  118. 11170   SOURCE$ = FLD$
  119. 11180  RETURN
  120. 11190  '
  121. 11200  'subr caps
  122. 11210  'Caps inpline$ up to ";".  Skips strings
  123. 11220  FOR I = 1 TO ENDPTR
  124. 11230    C$ = MID$(INPLINE$,I,1)
  125. 11240    'skip strings
  126. 11250     IF C$ <> "'" THEN 11290
  127. 11260       STRGEND = INSTR(I+1,INPLINE$,C$)
  128. 11270       IF STRGEND > 0 THEN I = STRGEND: GOTO 11300
  129. 11280    'convert
  130. 11290     IF ASC(C$) => 97 AND ASC(C$) <= 122 THEN C$ = CHR$(ASC(C$) - 32):                  MID$(INPLINE$,I,1) = C$
  131. 11300    NEXT I
  132. 11310  RETURN
  133. 11320  '=====================
  134. 11330  'GETFIELD
  135. 11340  'Starting at lineptr, trys to get next field in FLD$
  136. 11350  'Sets found if sucessful. Moves lineptr past field
  137. 11360  '=====================
  138. 11370  'find next non-delim or run off end
  139. 11380   WHILE LINEPTR <= ENDPTR
  140. 11390     IF INSTR(DELIM$,MID$(INPLINE$,LINEPTR,1)) = 0 THEN 11420
  141. 11400     LINEPTR = LINEPTR + 1
  142. 11410     WEND
  143. 11420  'past end?
  144. 11430   IF LINEPTR <= ENDPTR  THEN 11460
  145. 11440     FOUND = FALSE
  146. 11450     RETURN
  147. 11460  'strings end with '
  148. 11470   IF MID$(INPLINE$,LINEPTR,1) <> "'" THEN 11520
  149. 11480     STRGEND = INSTR(LINEPTR+1,INPLINE$,"'")
  150. 11490     IF STRGEND = 0 THEN 11520
  151. 11500       LINEPTR2 = STRGEND + 1
  152. 11510       GOTO 11580
  153. 11520  'else, find delim or go past end
  154. 11530   LINEPTR2 = LINEPTR
  155. 11540   WHILE LINEPTR2 <= ENDPTR
  156. 11550     IF INSTR(DELIM$,MID$(INPLINE$,LINEPTR2,1)) > 0 THEN 11580
  157. 11560     LINEPTR2 = LINEPTR2 + 1
  158. 11570     WEND
  159. 11580  'copy field
  160. 11590   FLD$ = MID$(INPLINE$,LINEPTR,LINEPTR2-LINEPTR)
  161. 11600  'lineptr past field, set found
  162. 11610   LINEPTR = LINEPTR2
  163. 11620   FOUND = TRUE
  164. 11630   RETURN
  165. 11640  '====================
  166. 11650  'NEWENTRY
  167. 11660  'Adds symbol to table
  168. 11670  '====================
  169. 11680  'bad?
  170. 11690   IF INSTR("1234567890-+",LEFT$(LABEL$,1)) = 0 THEN 11720
  171. 11700     MSG$ = "Illegal Label: " + LABEL$: GOSUB 19030
  172. 11710     LABEL$ = "": RETURN
  173. 11720  'already there?
  174. 11730   TARGET$ = LABEL$
  175. 11740   GOSUB 11990     'operand_lookup
  176. 11750   IF NOT FOUND THEN 11780
  177. 11760     MSG$ = "Duplicate definition of "+LABEL$+" ": GOSUB 19030
  178. 11770     RETURN
  179. 11780  'table full?
  180. 11790   IF NUMSYM < MAXSYM THEN 11820
  181. 11800     MSG$ = "Too many user symbols": GOSUB 19030
  182. 11810     RETURN
  183. 11820  'else make new entry
  184. 11830   NUMSYM = NUMSYM + 1
  185. 11840   SYM$(NUMSYM) = LABEL$
  186. 11850   VAL1(NUMSYM) = LOCTR
  187. 11860   SYMTYPE(NUMSYM) = NEAR
  188. 11870  RETURN
  189. 11880  '=================
  190. 11890  'CHECK_PHASE
  191. 11900  'Label value same both passes?
  192. 11910  '=================
  193. 11920  IF OP$ = "EQU" THEN 11980
  194. 11930  TARGET$ = LABEL$
  195. 11940  GOSUB 11990  'operand_lookup
  196. 11950  IF (SYMTYPE(TABLEPTR) AND (NEAR OR MEM)) = FALSE THEN 11980
  197. 11960    IF VAL1(TABLEPTR) = LOCTR THEN 11980
  198. 11970      MSG$ = "Phase Error": GOSUB 19030
  199. 11980  RETURN
  200. 11990  '=========================
  201. 12000  'OPERAND_LOOKUP
  202. 12010  'Trys to find TARGET$ in sym table. If there
  203. 12020  'sets FOUND true, & TABLEPTR to its position
  204. 12030  '=========================
  205. 12040  'scan table
  206. 12050   FOR TABLEPTR = 1 TO NUMSYM
  207. 12060     IF SYM$(TABLEPTR) = TARGET$ THEN 12110
  208. 12070     NEXT TABLEPTR
  209. 12080  'failure
  210. 12090   FOUND = FALSE
  211. 12100   RETURN
  212. 12110  'sucess
  213. 12120   FOUND = TRUE
  214. 12130   RETURN
  215. 12140  '========================
  216. 12150  'LOOKUP_OP
  217. 12160  'Given op-code in op$, & operand types in dtype &
  218. 12170  'stype, trys to find op in opcode table. If there
  219. 12180  'sets found true, & opptr to its position.
  220. 12190  '========================
  221. 12200  'binary search for good starting pt.
  222. 12210   MOVE = NUMOP: ST = MOVE/2
  223. 12220   WHILE MOVE >= 2
  224. 12230     MOVE = MOVE/2
  225. 12240     IF OP$ > OPCODE$(ST) THEN ST = ST + MOVE ELSE ST = ST - MOVE
  226. 12250     IF ST < 1 THEN ST = 1
  227. 12260     IF ST > NUMOP THEN ST = NUMOP
  228. 12270     WEND
  229. 12280  'match all 3 fields
  230. 12290   FOR OPPTR = ST TO NUMOP
  231. 12300     IF OPCODE$(OPPTR) > OP$ THEN 12360   'failed
  232. 12310     IF OPCODE$(OPPTR) <> OP$ THEN 12350
  233. 12320     IF (SRCTYPE(OPPTR) AND STYPE) = FALSE THEN 12350
  234. 12330     IF (DSTTYPE(OPPTR) AND DTYPE) = FALSE THEN 12350
  235. 12340     GOTO 12390 'found!
  236. 12350     NEXT OPPTR
  237. 12360  'failure
  238. 12370   FOUND = FALSE
  239. 12380   RETURN
  240. 12390  'success
  241. 12400   FOUND = TRUE
  242. 12410   RETURN
  243. 12420  '===========================
  244. 12430  'UPDATE_LOCTR
  245. 12440  'Decodes op & advances loctr
  246. 12450  '2nd pass, generate obj code
  247. 12460  '===========================
  248. 12470  'set operand types & vals
  249. 12480    'dest
  250. 12490     TARGET$ = DEST$: GOSUB 12750  'type_operand
  251. 12500     DTYPE = TARGTYPE: DVAL1 = TARGVAL1: DVAL2 = TARGVAL2
  252. 12510    'src
  253. 12520    'special case: RET op
  254. 12530     IF OP$ = "RET" THEN STYPE = PROCTYPE(STKTOP): GOTO 12570
  255. 12540    'normal
  256. 12550     TARGET$ = SOURCE$: GOSUB 12750   'type_operand
  257. 12560     STYPE = TARGTYPE: SVAL1 = TARGVAL1: SVAL2 = TARGVAL2
  258. 12570  'find op in op table (not there: error)
  259. 12580   TARGET$ = OP$
  260. 12590   GOSUB 12140   'lookup_op
  261. 12600   IF FOUND THEN 12700
  262. 12610     IF PASS = 1 THEN RETURN
  263. 12620     MSG$ = "Syntax Error: "+ OP$ + " " + STR$(DTYPE) + " " + STR$(STYPE)
  264. 12630     GOSUB 19030
  265. 12640     IF ((ACUM8 OR ACUM16 OR REG8 OR REG16 OR SEGR OR CS)                                AND (DTYPE OR STYPE)) THEN 12690
  266. 12650     IF (STYPE AND (NONE OR IMMED8 OR IMMED16)) = FALSE THEN 12690
  267. 12660     IF INSTR("BW",RIGHT$(OP$,1)) <> 0 THEN 12690
  268. 12670        DIAGFLAG = TRUE
  269. 12680        MSG$ = "Specify word or byte operation": GOSUB 19030
  270. 12690     RETURN
  271. 12700   FLAG = OFLAG(OPPTR)
  272. 12710  '
  273. 12720  'branch to update loctr
  274. 12730   IF FLAG AND MACHOP THEN GOSUB 14890 ELSE GOSUB 15640
  275. 12740  RETURN
  276. 12750  '=====================
  277. 12760  'TYPE_OPERAND
  278. 12770  'Sets TARGTYPE to TARGET$'s type.  Sets
  279. 12780  'TARGVAL1 to its value. If a reg, sets
  280. 12790  'TARVAL2 to its val2. If offset appears
  281. 12800  'NEEDOFFSET & OFFSET are set.
  282. 12810  '======================
  283. 12820  'any operand?
  284. 12830   IF LEN(TARGET$) > 0 THEN 12860
  285. 12840     TARGTYPE = NONE
  286. 12850     RETURN
  287. 12860  'in sym table?
  288. 12870   GOSUB 11990
  289. 12880   IF NOT FOUND THEN 12920
  290. 12890     TARGTYPE = SYMTYPE(TABLEPTR): TARGVAL1 = VAL1(TABLEPTR)
  291. 12900     IF TABLEPTR <= PREDEF THEN TARGVAL2 = VAL2(TABLEPTR)
  292. 12910     RETURN
  293. 12920  'number?
  294. 12930   GOSUB 13320
  295. 12940   IF NOT FOUND THEN 12970
  296. 12950     TARGTYPE = NUMTYPE: TARGVAL1 = NUMVAL
  297. 12960     RETURN
  298. 12970  'mem ref?
  299. 12980   GOSUB 13690
  300. 12990   IF NOT FOUND THEN 13020
  301. 13000     TARGTYPE = MEM: TARGVAL1 = MEMADDR
  302. 13010     RETURN
  303. 13020  'offset off register?
  304. 13030   GOSUB 13990
  305. 13040   IF NOT FOUND THEN 13080
  306. 13050     TARGTYPE = MEMREG: TARGVAL1 = REGVAL
  307. 13060     RETURN
  308. 13070  'offset?
  309. 13080   GOSUB 14550
  310. 13090   IF NOT FOUND THEN 13120
  311. 13100     TARGTYPE = OFFSETYPE: TARGVAL1 = OFFSETVAL
  312. 13110     RETURN
  313. 13120  'char?
  314. 13130   GOSUB 14780
  315. 13140   IF NOT FOUND THEN 13170
  316. 13150     TARGTYPE = IMMED8 OR IMMED16: TARGVAL1 = CHARVAL
  317. 13160     RETURN
  318. 13170  'string?
  319. 13180   IF LEFT$(TARGET$,1) <> "'" THEN 13210
  320. 13190     TARGTYPE = STRING
  321. 13200     RETURN
  322. 13210  'not found? assume label or mem (pass 2 error)
  323. 13220   IF PASS = 1 THEN 13300
  324. 13230     MSG$ = "Undefined Symbol "+TARGET$: GOSUB 19030
  325. 13240    'look like hex?
  326. 13250     IF RIGHT$(TARGET$,1) <> "H" OR LEN(TARGET$) > 5 THEN 13300
  327. 13260     FOR I = 1 TO LEN(TARGET$)-1
  328. 13270       IF INSTR("1234567890ABCDEF", MID$(TARGET$,I,1)) = 0 THEN 13300
  329. 13280       NEXT I
  330. 13290     MSG$ = "Add leading zero to hex constant":DIAGFLAG = TRUE: GOSUB 19030
  331. 13300   TARGTYPE = NEAR OR MEM
  332. 13310  RETURN
  333. 13320  '=====================
  334. 13330  'TEST_NUMBER
  335. 13340  'Trys to interpret TARGET$ as a num
  336. 13350  'If sucessful, sets FOUND true, NUMVAL
  337. 13360  'to its value and NUMTYPE to its type
  338. 13370  '=====================
  339. 13380  FOUND = FALSE
  340. 13390  IF INSTR("1234567890-+",LEFT$(TARGET$,1)) = 0 THEN RETURN
  341. 13400  TN$ = TARGET$  'make copy
  342. 13410  IF LEFT$(TN$,1) = "0" THEN TN$ = RIGHT$(TN$,LEN(TN$)-1)
  343. 13420  'hex?
  344. 13430   IF (RIGHT$(TN$,1) <> "H") OR (LEN(TN$) > 5) THEN 13560
  345. 13440    'lop off H
  346. 13450     TN$ = LEFT$(TN$,LEN(TN$)-1)
  347. 13460    'non-hex digits?
  348. 13470     I = 1
  349. 13480     FOR I = 1 TO LEN(TN$)
  350. 13490       C$ = MID$(TN$,I,1)
  351. 13500       IF INSTR("0123456789ABCDEF",C$) = 0 THEN RETURN
  352. 13510       NEXT I
  353. 13520    'get value
  354. 13530     NUMVAL = VAL("&H"+TN$)
  355. 13540    'set type, return
  356. 13550     GOTO 13650
  357. 13560  'dec?
  358. 13570    'non-dec digits?
  359. 13580     FOR I = 1 TO LEN(TN$)
  360. 13590       C$ = MID$(TN$,I,1)
  361. 13600       IF INSTR("0123456789-+",C$) = 0 THEN RETURN
  362. 13610       NEXT I
  363. 13620    'get value (overflow?)
  364. 13630     NVAL# = VAL(TN$)
  365. 13640  IF NVAL# < 32768 AND NVAL# > -32769 THEN NUMVAL = NVAL# ELSE RETURN
  366. 13650  'sucess exit
  367. 13660   FOUND = TRUE
  368. 13670   IF LEN(HEX$(NUMVAL)) < 3  THEN NUMTYPE = IMMED16 OR IMMED8                        ELSE NUMTYPE = IMMED16
  369. 13680  RETURN
  370. 13690  '==================================
  371. 13700  'MEMREF
  372. 13710  'Trys to interpret target$ as a mem
  373. 13720  'ref.  If so, sets FOUND true, &
  374. 13730  'MEMADDR to the address referenced.
  375. 13740  '==================================
  376. 13750  MR$ = TARGET$  'save copy
  377. 13760  '[]?
  378. 13770   IF LEFT$(MR$,1) <> "[" OR RIGHT$(MR$,1) <> "]" THEN RETURN
  379. 13780  'strip []
  380. 13790   TARGET$ = MID$(MR$,2,LEN(MR$)-2)
  381. 13800  'try to parse as addr
  382. 13810   'number?
  383. 13820    GOSUB 13320
  384. 13830    IF NOT FOUND THEN 13860
  385. 13840      MEMADDR = NUMVAL
  386. 13850      GOTO 13960 'exit
  387. 13860   'symbol?
  388. 13870    GOSUB 11990
  389. 13880    IF NOT FOUND THEN 13920
  390. 13890      IF (SYMTYPE(TABLEPTR) AND IMMED16) = FALSE THEN 13920
  391. 13900        MEMADDR = VAL1(TABLEPTR)
  392. 13910        GOTO 13960 'exit
  393. 13920  'failure
  394. 13930   FOUND = FALSE
  395. 13940   TARGET$ = MR$
  396. 13950   RETURN
  397. 13960  'sucess
  398. 13970   TARGET$ = MR$
  399. 13980   RETURN
  400. 13990  '=======================================
  401. 14000  'PARSE_DISP_OFF_REG
  402. 14010  'Trys to parse TARGET$ as offset off reg
  403. 14020  'If so, sets FOUND true, sets NEEDOFFSET
  404. 14030  'to offset's type, and OFFSET its value
  405. 14040  '=======================================
  406. 14050  PDOR$ = TARGET$  'save copy
  407. 14060  '
  408. 14070  'special case
  409. 14080   IF TARGET$ = "[BP]" THEN REGVAL = 6: NEEDOFFSET = IMMED8: OFFSET = 0:              GOTO 14470
  410. 14090  '
  411. 14100  'parse reg
  412. 14110   'set ptr to candidate
  413. 14120    PTR = INSTR(TARGET$,"[")
  414. 14130    IF PTR <= 1 THEN 14510  'no disp, exit
  415. 14140   'isolate candidate
  416. 14150    REG$ = RIGHT$(PDOR$,LEN(PDOR$)-PTR+1)
  417. 14160   'valid reg?
  418. 14170    IF REG$ = "[BP]" THEN REGVAL = 6: GOTO 14240
  419. 14180    TARGET$ = REG$
  420. 14190    GOSUB 11990  'operand_lookup
  421. 14200    IF NOT FOUND OR SYMTYPE(TABLEPTR) <> MEMREG THEN 14510
  422. 14210     'save reg value
  423. 14220      REGVAL = VAL1(TABLEPTR)
  424. 14230  '
  425. 14240  'now parse disp.
  426. 14250   'isolate candidate
  427. 14260    DISP$ = LEFT$(PDOR$,PTR-1)
  428. 14270   'valid disp?
  429. 14280    TARGET$ = DISP$
  430. 14290     'might be symbol
  431. 14300      GOSUB 11990
  432. 14310      IF NOT FOUND THEN 14360   'not sym
  433. 14320      IF (SYMTYPE(TABLEPTR) AND (IMMED16 OR IMMED8)) = FALSE THEN 14360
  434. 14330        OFFSET = VAL1(TABLEPTR)
  435. 14340        NEEDOFFSET  = SYMTYPE(TABLEPTR)
  436. 14350        GOTO 14470
  437. 14360     'or number
  438. 14370      GOSUB 13320
  439. 14380      IF NOT FOUND THEN 14420
  440. 14390        OFFSET = NUMVAL
  441. 14400        IF OFFSET > 127 OR OFFSET < -128                                                   THEN NEEDOFFSET  = IMMED16 ELSE NEEDOFFSET = IMMED8
  442. 14410        GOTO 14470
  443. 14420     'or offset
  444. 14430      GOSUB 14550 'offset
  445. 14440      IF NOT FOUND THEN 14510
  446. 14450        OFFSET = OFFSETVAL
  447. 14460        NEEDOFFSET = IMMED16
  448. 14470  'sucess
  449. 14480   TARGET$ = PDOR$
  450. 14490   FOUND = TRUE
  451. 14500   RETURN
  452. 14510  'failure
  453. 14520   TARGET$ = PDOR$
  454. 14530   FOUND = FALSE
  455. 14540   RETURN
  456. 14550  '==========================
  457. 14560  'OFFSET
  458. 14570  'Trys to interpret TARGET$ as an offset
  459. 14580  'If sucessful, set FOUND, set OFFSETYPE
  460. 14590  'to immed16, TARGVAL1 to label's offset
  461. 14600  '==========================
  462. 14610  OS$ = TARGET$
  463. 14620  IF LEFT$(OS$,7) <> "OFFSET(" THEN FOUND = FALSE: RETURN
  464. 14630  IF PASS = 1 THEN 14740
  465. 14640  'isolate label
  466. 14650   TARGET$ = MID$(TARGET$,8,LEN(TARGET$)-8)
  467. 14660  'look it up
  468. 14670   GOSUB 11990
  469. 14680  IF FOUND AND (SYMTYPE(TABLEPTR) AND (MEM OR NEAR)) THEN 14720
  470. 14690    MSG$ = "Illegal or undefined argument for Offset": GOSUB 19030
  471. 14700    OFFSETVAL = 0
  472. 14710    GOTO 14740
  473. 14720  OFFSETVAL = VAL1(TABLEPTR)
  474. 14730  '
  475. 14740  FOUND = TRUE
  476. 14750  OFFSETYPE = IMMED16
  477. 14760  TARGET$ = OS$
  478. 14770  RETURN
  479. 14780  '=================
  480. 14790  'CHAR
  481. 14800  'Trys to parse TARGET$ as char
  482. 14810  '=================
  483. 14820  FOUND = FALSE
  484. 14830  IF LEN(TARGET$) <> 3 THEN RETURN
  485. 14840  IF LEFT$(TARGET$,1) <> "'" THEN RETURN
  486. 14850  IF RIGHT$(TARGET$,1) <> "'" THEN RETURN
  487. 14860    FOUND = TRUE
  488. 14870    CHARVAL = ASC(MID$(TARGET$,2,1))
  489. 14880  RETURN
  490. 14890  '=============================
  491. 14900  'MACHOP
  492. 14910  'Updates loctr based on op len
  493. 14920  'On pass 2, generates obj. code
  494. 14930  '==============================
  495. 14940  GOSUB 15510  'op_type
  496. 14950  '
  497. 14960  'opcode
  498. 14970   LOCTR = LOCTR + 1
  499. 14980   IF PASS = 2 THEN GOSUB 15700  'build_opcode
  500. 14990  '
  501. 15000  '2nd op byte?
  502. 15010   IF (OPVAL(OPPTR) <> &HD5) AND (OPVAL(OPPTR) <> &HD4) THEN 15050
  503. 15020     LOCTR = LOCTR + 1
  504. 15030     IF PASS = 2 THEN OBJLEN = OBJLEN + 1: OBJ(OBJLEN) = &HA
  505. 15040  '
  506. 15050  'room for m. byte disp. (must go here)
  507. 15060   IF NEEDOFFSET = NONE THEN 15090
  508. 15070     IF NEEDOFFSET AND IMMED8 THEN LOCTR = LOCTR+1: ELSE LOCTR = LOCTR+2
  509. 15080  '
  510. 15090  'direct addr. mode byte? leave room for addr
  511. 15100   IF (FLAG AND (NEEDMODEBYTE OR NEEDEXT)) = FALSE THEN 15130
  512. 15110     IF (DTYPE OR STYPE) AND MEM THEN LOCTR = LOCTR + 2
  513. 15120  '
  514. 15130  'ext. byte?
  515. 15140   IF (FLAG AND NEEDEXT) = FALSE THEN 15180
  516. 15150     LOCTR = LOCTR + 1
  517. 15160     IF PASS = 2 THEN GOSUB 15910   'build_ext
  518. 15170  '
  519. 15180  'mode byte?
  520. 15190   IF (FLAG AND NEEDMODEBYTE) = FALSE THEN 15230
  521. 15200     LOCTR = LOCTR + 1
  522. 15210     IF PASS = 2 THEN GOSUB 16030  'build_modebyte
  523. 15220  '
  524. 15230  '8 bit disp?
  525. 15240   IF (FLAG AND NEEDISP8) = FALSE THEN 15280
  526. 15250     LOCTR = LOCTR + 1
  527. 15260     IF PASS = 2 THEN GOSUB 16480  'build_disp8
  528. 15270  '
  529. 15280  '16 bit disp?
  530. 15290   IF (FLAG AND NEEDISP16) = FALSE THEN 15330
  531. 15300     LOCTR = LOCTR + 2
  532. 15310     IF PASS = 2 THEN GOSUB 16650 'build_disp16
  533. 15320  '
  534. 15330  'immed byte?
  535. 15340   IF (FLAG AND NEEDIMMED8) = FALSE THEN 15370
  536. 15350     LOCTR = LOCTR + 1
  537. 15360     IF PASS = 2 THEN GOSUB 16910
  538. 15370   IF WORD OR ((FLAG AND NEEDIMMED) = FALSE) THEN 15410
  539. 15380     LOCTR = LOCTR + 1
  540. 15390     IF PASS = 2 THEN GOSUB 16910   'build_immed8
  541. 15400  '
  542. 15410  'immed word(s)?
  543. 15420   IF NOT(WORD) OR ((FLAG AND NEEDIMMED) = FALSE) THEN 15460
  544. 15430     IF DTYPE AND IMMED16 THEN LOCTR = LOCTR + 4 ELSE LOCTR = LOCTR + 2
  545. 15440     IF PASS = 2 THEN GOSUB 16780  'build_immed16
  546. 15450  '
  547. 15460  'mem addr?
  548. 15470   IF (FLAG AND NEEDMEM) = FALSE THEN 15500
  549. 15480     LOCTR = LOCTR + 2
  550. 15490     IF PASS = 2 THEN GOSUB 17020  'mem_addr
  551. 15500  RETURN
  552. 15510  '==================
  553. 15520  'OP_TYPE
  554. 15530  'Decides between word & byte ops
  555. 15540  '==================
  556. 15550  IF (DTYPE OR STYPE) AND (REG16 OR ACUM16 OR SEGR OR CS) THEN 15580
  557. 15560  IF (DTYPE OR STYPE) AND (REG8 OR ACUM8) THEN 15610
  558. 15570  IF RIGHT$(OP$,1) = "B" THEN 15610
  559. 15580  'word
  560. 15590   WORD = TRUE
  561. 15600   RETURN
  562. 15610  'byte
  563. 15620   WORD = FALSE
  564. 15630   RETURN
  565. 15640  '=========
  566. 15650  'PSEUDO-OP
  567. 15660  '=========
  568. 15670  ON OPVAL(OPPTR) GOSUB 17140,17270,17320,17810,17970,18070,18150,18190
  569. 15680  '                      EQU   ORG   DB    DS   PROC  ENDP  BSAVE EJECT
  570. 15690  RETURN
  571. 15700  '==================
  572. 15710  'BUILD_OPCODE
  573. 15720  'Builds opcode in OBJ
  574. 15730  '==================
  575. 15740  OBJLEN = OBJLEN + 1
  576. 15750  OBJ(OBJLEN) = OPVAL(OPPTR)
  577. 15760  '
  578. 15770  'reg field?
  579. 15780   IF (FLAG AND ADDREG) = FALSE THEN 15840
  580. 15790     'seg reg
  581. 15800     IF DTYPE AND (SEGR OR CS) THEN R = DVAL2: GOTO 15830
  582. 15810     'normal reg
  583. 15820     IF (FLAG AND DIRECTION) THEN R = SVAL2/8 ELSE R = DVAL2/8
  584. 15830     OBJ(OBJLEN) = OBJ(OBJLEN) + R
  585. 15840  'word bit?
  586. 15850   IF (FLAG AND AUTOW) = FALSE THEN 15870
  587. 15860     IF WORD THEN OBJ(OBJLEN) = OBJ(OBJLEN) + 1
  588. 15870  'count bit?
  589. 15880   IF (FLAG AND AUTOC) = FALSE THEN 15900
  590. 15890     IF STYPE AND CL THEN OBJ(OBJLEN) = OBJ(OBJLEN) + 2
  591. 15900  RETURN
  592. 15910  '===================================
  593. 15920  'BUILD_EXTENSION_BYTE
  594. 15930  'Builds opcode ext byte.  Ext val is
  595. 15940  'extracted from bits 3-5 of flag word
  596. 15950  '====================================
  597. 15960  'get ext
  598. 15970   MASK = &H38
  599. 15980   EXT = FLAG AND MASK
  600. 15990  'define proper opd as ext & build
  601. 16000   IF FLAG AND DIRECTION THEN DVAL2 = EXT ELSE SVAL2 = EXT
  602. 16010   GOSUB 16030  'build_modebyte
  603. 16020  RETURN
  604. 16030  '=========================
  605. 16040  'BUILD_MODE_BYTE
  606. 16050  'Given direction flag, memreg values in dval1 & sval1 &
  607. 16060  'reg values in dval2 & sval2, builds an addressing mode
  608. 16070  'byte.  If necessary, also builds displacement byte(s).
  609. 16080  '=========================
  610. 16090  OBJLEN = OBJLEN + 1
  611. 16100  'special case: direct mem. addressing?
  612. 16110   IF ((DTYPE OR STYPE) AND MEM) = FALSE THEN 16170
  613. 16120     IF DTYPE = MEM THEN  M = SVAL2 ELSE M = DVAL2
  614. 16130       OBJ(OBJLEN) = 6 + M
  615. 16140       GOSUB 17020  'build_mem_addr
  616. 16150       RETURN
  617. 16160  'normal mode byte
  618. 16170  'opds in normal or reverse order?
  619. 16180   IF FLAG AND DIRECTION THEN M = SVAL1 + DVAL2 ELSE M = DVAL1 + SVAL2
  620. 16190   OBJ(OBJLEN) = M
  621. 16200  'offset byte(s)?
  622. 16210  IF NEEDOFFSET = NONE THEN 16370
  623. 16220  '8 bit disp.
  624. 16230  IF OFFSET > 127 OR OFFSET < -128 THEN 16300
  625. 16240    OBJ(OBJLEN) = OBJ(OBJLEN) + 64  'set mod field
  626. 16250    'crunch neg. offset to 8 bits
  627. 16260      IF OFFSET < 0 THEN OFFSET = OFFSET AND &HFF
  628. 16270    OBJLEN = OBJLEN + 1
  629. 16280    OBJ(OBJLEN) = OFFSET
  630. 16290    RETURN
  631. 16300  '16 bit disp.
  632. 16310   OBJ(OBJLEN) = OBJ(OBJLEN) + 128  'set mod field
  633. 16320   OBJLEN = OBJLEN + 2
  634. 16330   'convert to hi/low form
  635. 16340      NUMLOW = OFFSET: GOSUB 16380  'hi/low
  636. 16350   OBJ(OBJLEN-1) = NUMLOW
  637. 16360   OBJ(OBJLEN) = NUMHIGH
  638. 16370  RETURN
  639. 16380  '=====================================
  640. 16390  'HI/LOW
  641. 16400  'Splits 16 bit number in numlow into 2
  642. 16410  'byte-sized chunks in numhigh & numlow
  643. 16420  '=====================================
  644. 16430  H$ = HEX$(NUMLOW)
  645. 16440  H$ = STRING$(4-LEN(H$),"0") + H$
  646. 16450  NUMLOW =  VAL("&H" + RIGHT$(H$,2))
  647. 16460  NUMHIGH = VAL("&H" + LEFT$(H$,2))
  648. 16470  RETURN
  649. 16480  '=========================
  650. 16490  'BUILD_DISP8
  651. 16500  'Builds displacement byte.  Prints
  652. 16510  'error msg if disp. exceeds 127
  653. 16520  '=========================
  654. 16530  'calc disp.
  655. 16540   D = DVAL1 - LOCTR
  656. 16550  'check size
  657. 16560   IF ABS(D) < 128 THEN 16590
  658. 16570     D = 0
  659. 16580     IF PASS = 2 THEN MSG$ = "Too far for short jump": GOSUB 19030
  660. 16590  'if neg. crunch to 8 bits
  661. 16600   IF D < 0 THEN D = D AND &HFF
  662. 16610  'build obj. code
  663. 16620   OBJLEN = OBJLEN + 1
  664. 16630   OBJ(OBJLEN) = D
  665. 16640  RETURN
  666. 16650  '========================
  667. 16660  'BUILD_DISP16
  668. 16670  'Builds displacement word
  669. 16680  '========================
  670. 16690  'calc disp.
  671. 16700   D = DVAL1 - LOCTR
  672. 16710  IF OP$ = "JMP" AND (D < 128 AND D > -129) THEN DIAGFLAG = TRUE:                   MSG$ = "Could use JMPS": GOSUB 19030
  673. 16720  'build obj. code
  674. 16730   NUMLOW = D: GOSUB 16380  'hi/low
  675. 16740   OBJLEN = OBJLEN + 2
  676. 16750   OBJ(OBJLEN-1) = NUMLOW
  677. 16760   OBJ(OBJLEN) = NUMHIGH
  678. 16770  RETURN
  679. 16780  '============================
  680. 16790  'BUILD_IMMED16
  681. 16800  'Builds word(s) of immed data
  682. 16810  '============================
  683. 16820  IF DTYPE AND IMMED16 THEN IVAL = DVAL1: GOSUB 16850
  684. 16830  IF STYPE AND IMMED16 THEN IVAL = SVAL1: GOSUB 16850
  685. 16840  RETURN
  686. 16850  'subroutine immed16
  687. 16860  NUMLOW = IVAL: GOSUB 16380   'hi/low
  688. 16870  OBJLEN = OBJLEN + 2
  689. 16880  OBJ(OBJLEN-1) = NUMLOW
  690. 16890  OBJ(OBJLEN) = NUMHIGH
  691. 16900  RETURN
  692. 16910  '=========================
  693. 16920  'BUILD_IMMED8
  694. 16930  'Builds byte of immed data
  695. 16940  '=========================
  696. 16950  IF DTYPE AND IMMED8 THEN IVAL = DVAL1: GOSUB 16980
  697. 16960  IF STYPE AND IMMED8 THEN IVAL = SVAL1: GOSUB 16980
  698. 16970  RETURN
  699. 16980  'sub. immed8
  700. 16990  OBJLEN = OBJLEN + 1
  701. 17000  OBJ(OBJLEN) = IVAL
  702. 17010  RETURN
  703. 17020  '======================
  704. 17030  'MEMREF
  705. 17040  'Builds a mem addr word
  706. 17050  '======================
  707. 17060  'get addr in hi/low form
  708. 17070   IF DTYPE AND MEM THEN NUMLOW = DVAL1 ELSE NUMLOW = SVAL1
  709. 17080   GOSUB 16380
  710. 17090  'build word
  711. 17100   OBJLEN = OBJLEN + 2
  712. 17110   OBJ(OBJLEN-1) = NUMLOW
  713. 17120   OBJ(OBJLEN) = NUMHIGH
  714. 17130  RETURN
  715. 17140  '=====
  716. 17150  'EQU
  717. 17160  '=====
  718. 17170  IF (LABEL$ <> "")  THEN 17200
  719. 17180    IF PASS = 2 THEN MSG$ = "EQU without symbol": GOSUB 19030
  720. 17190    RETURN
  721. 17200  IF PASS = 2 THEN 17260
  722. 17210  IF DTYPE <> (NEAR OR MEM) THEN 17240   'pass 1 default
  723. 17220    MSG$ = "EQU with forward reference": GOSUB 19030
  724. 17230    RETURN
  725. 17240  VAL1(NUMSYM) = DVAL1
  726. 17250  SYMTYPE(NUMSYM) = DTYPE
  727. 17260  RETURN
  728. 17270  '=====
  729. 17280  'ORG
  730. 17290  '=====
  731. 17300  LOCTR = DVAL1
  732. 17310  RETURN
  733. 17320  '=====
  734. 17330  'DB
  735. 17340  '=====
  736. 17350  IF PASS = 2 THEN 17380
  737. 17360  'label? type = mem
  738. 17370   IF LABEL$ <> "" THEN SYMTYPE(NUMSYM) = MEM
  739. 17380  'scan, building obj. code
  740. 17390   LINEPTR = OPDPTR: LINEPTR2 = OPDPTR
  741. 17400   WHILE LINEPTR < ENDPTR
  742. 17410    'get operand
  743. 17420     GOSUB 11320  'get_field
  744. 17430     IF NOT FOUND THEN 17630  'exit
  745. 17440    'branch for byte or string
  746. 17450     TARGET$ = FLD$: GOSUB 13320 'test_number
  747. 17460     IF NOT FOUND THEN 17490
  748. 17470       GOSUB 17650  'build_byte
  749. 17480       GOTO 17620
  750. 17490     GOSUB 11990 'operand lookup
  751. 17500     IF (NOT FOUND) OR ((SYMTYPE(TABLEPTR) AND (IMMED8 OR IMMED16)) = FALSE)            THEN 17530
  752. 17510        NUMVAL = VAL1(TABLEPTR): NUMTYPE = SYMTYPE(TABLEPTR): GOSUB 17650
  753. 17520        GOTO 17620
  754. 17530     GOSUB 14550 'offset
  755. 17540     IF NOT FOUND THEN 17570
  756. 17550        NUMVAL = OFFSETVAL: NUMTYPE = IMMED16: GOSUB 17650
  757. 17560        GOTO 17620
  758. 17570     IF LEFT$(FLD$,1) <> "'" THEN 17600
  759. 17580       GOSUB 17740  'build_stg
  760. 17590       GOTO 17620
  761. 17600    'not byte or string? pass 2 error
  762. 17610     IF PASS = 2 THEN MSG$ = "Unrecognized operand "+FLD$: GOSUB 19030
  763. 17620    WEND
  764. 17630  LOCTR = LOCTR + OBJLEN
  765. 17640  RETURN
  766. 17650  'build_byte
  767. 17660  IF (NUMTYPE AND IMMED8) = FALSE THEN 17700
  768. 17670  OBJLEN = OBJLEN + 1
  769. 17680  OBJ(OBJLEN) = NUMVAL
  770. 17690  RETURN
  771. 17700  NUMLOW = NUMVAL: GOSUB 16430 'hi/low
  772. 17710  OBJLEN = OBJLEN + 1: OBJ(OBJLEN) = NUMLOW
  773. 17720  OBJLEN = OBJLEN + 1: OBJ(OBJLEN) = NUMHIGH
  774. 17730  RETURN
  775. 17740  'build_stg
  776. 17750  FLD$ = MID$(FLD$,2,LEN(FLD$)-2) 'strip off 's
  777. 17760  FOR I = 1 TO LEN(FLD$)
  778. 17770    OBJLEN = OBJLEN + 1
  779. 17780    OBJ(OBJLEN) = ASC(MID$(FLD$,I,1))
  780. 17790    NEXT I
  781. 17800  RETURN
  782. 17810  '=====
  783. 17820  'DS
  784. 17830  '=====
  785. 17840  DSFLAG = TRUE  'signal a ds
  786. 17850  IF PASS = 2 THEN 17880 'skip type setting?
  787. 17860  'label?
  788. 17870   IF LABEL$ <> "" THEN SYMTYPE(NUMSYM) = MEM
  789. 17880  'output code
  790. 17890   IF STYPE AND IMMED8 THEN DSVAL = SVAL1 ELSE DSVAL = 0
  791. 17900  'pass 2, generate obj. code directly
  792. 17910   IF PASS = 1 THEN 17950
  793. 17920     FOR I = 1 TO DVAL1
  794. 17930       LSET BYTE$ = CHR$(DSVAL): PUT #3
  795. 17940       NEXT I
  796. 17950   LOCTR = LOCTR + DVAL1: BYTESGEN = BYTESGEN + DVAL1
  797. 17960  RETURN
  798. 17970  '======
  799. 17980  'PROC
  800. 17990  '======
  801. 18000  IF STKTOP < MAXSTK THEN 18030
  802. 18010    IF PASS = 2 THEN MSG$ = "Procedures nested too deeply": GOSUB 19030
  803. 18020    RETURN
  804. 18030  'push new proc type
  805. 18040   STKTOP = STKTOP + 1
  806. 18050   PROCTYPE(STKTOP) = DTYPE
  807. 18060  RETURN
  808. 18070  '======
  809. 18080  'ENDP
  810. 18090  '======
  811. 18100  IF STKTOP > 0 THEN 18130
  812. 18110    IF PASS = 2 THEN MSG$ = "ENDP without PROC": GOSUB 19030
  813. 18120    RETURN
  814. 18130  STKTOP = STKTOP - 1
  815. 18140  RETURN
  816. 18150  '=====
  817. 18160  'BSAVE
  818. 18170  '=====
  819. 18180  BASCODE = TRUE: RETURN
  820. 18190  '=====
  821. 18200  'EJECT
  822. 18210  '=====
  823. 18220  IF PASS = 1 THEN RETURN
  824. 18230  LINESUSED = LINENUM + DIAG + ERRS + XTRA
  825. 18240  PAGEPOS = LINESUSED MOD PAGELEN
  826. 18250  GOSUB 18750
  827. 18260  RETURN
  828. 18270  '===============
  829. 18280  'OUTPUT
  830. 18290  'Outputs obj code & listing
  831. 18300  '===============
  832. 18310  'src to scrn for errors
  833. 18320    IF ERRORFLAG AND (L$ <> "scrn:") THEN PRINT INPLINE$
  834. 18330  'update # of bytes
  835. 18340   BYTESGEN = BYTESGEN + OBJLEN
  836. 18350  IF DSFLAG THEN H$ = HEX$(LOCTR-DVAL1) ELSE H$ = HEX$(LOCTR-OBJLEN)
  837. 18360  H$ = STRING$(4-LEN(H$),"0") + H$
  838. 18370  PRINT#2, TAB(1) H$;
  839. 18380  'first 6 bytes
  840. 18390   I = 1
  841. 18400   PRINT#2, TAB(6)
  842. 18410   WHILE I <= 6
  843. 18420     IF I > OBJLEN THEN 18490
  844. 18430     LSET BYTE$ = CHR$(OBJ(I)): PUT #3
  845. 18440     H$ = HEX$(OBJ(I)): IF LEN(H$) = 1 THEN H$ = "0" + H$
  846. 18450     PRINT#2, H$;
  847. 18460     I = I + 1
  848. 18470     WEND
  849. 18480  '
  850. 18490  'source (truncate?)
  851. 18500   PRINT#2, TAB(19)
  852. 18510   PRINT#2, USING "####"; LINENUM;
  853. 18520   PRINT#2, SPACE$(2) LEFT$(INPLINE$, LWIDTH-26)
  854. 18530  '
  855. 18540  'formfeed?
  856. 18550   GOSUB 18670
  857. 18560  '
  858. 18570  'rest of obj. code
  859. 18580   WHILE I <= OBJLEN
  860. 18590     IF I MOD 6 = 1 THEN PRINT#2, TAB(6): XTRA = XTRA + 1: GOSUB 18670
  861. 18600     LSET BYTE$ = CHR$(OBJ(I)): PUT #3
  862. 18610     H$ = HEX$(OBJ(I)): IF LEN(H$) = 1 THEN H$ = "0" + H$
  863. 18620     PRINT#2, H$;
  864. 18630     I = I + 1
  865. 18640     WEND
  866. 18650   IF OBJLEN > 6 THEN PRINT#2,: GOSUB 18670
  867. 18660  RETURN
  868. 18670  '==========
  869. 18680  'NEEDEJECT?
  870. 18690  '==========
  871. 18700  IF L$ <> "lpt1:" THEN RETURN
  872. 18710  LINESUSED = LINENUM + DIAG + ERRS + XTRA
  873. 18720  PAGEPOS = LINESUSED MOD PAGELEN
  874. 18730  IF PAGEPOS > MAXLINES THEN GOSUB 18750
  875. 18740  RETURN
  876. 18750  '===========================
  877. 18760  'FORMFEED
  878. 18770  'Advances to next page given
  879. 18780  'current position in PAGEPOS
  880. 18790  '===========================
  881. 18800  IF L$ <> "lpt1:" THEN RETURN
  882. 18810  FOR J = 1 TO (PAGELEN - PAGEPOS)
  883. 18820    PRINT#2,
  884. 18830    NEXT J
  885. 18840  XTRA = XTRA + PAGELEN - PAGEPOS
  886. 18850  PAGE = PAGE + 1: GOSUB 19840 'header
  887. 18860  RETURN
  888. 18870  '==========
  889. 18880  'PASS2_INIT
  890. 18890  '==========
  891. 18900  CLOSE 1: OPEN SC$ FOR INPUT AS 1
  892. 18910  IF NOT BASCODE THEN 19000
  893. 18920   'build bsave header
  894. 18930    LSET BYTE$ = CHR$(253): PUT 3
  895. 18940    FOR I = 1 TO 4
  896. 18950      LSET BYTE$ = CHR$(0): PUT 3
  897. 18960      NEXT I
  898. 18970    NUMLOW = LOCTR: GOSUB 16380 'hi/low
  899. 18980    LSET BYTE$ = CHR$(NUMLOW): PUT 3
  900. 18990    LSET BYTE$ = CHR$(NUMHIGH): PUT 3
  901. 19000  PASS = 2: LOCTR = 256: BYTESGEN = 0
  902. 19010  TOTALINES = LINENUM: LINENUM = 0
  903. 19020  RETURN
  904. 19030  '=====================
  905. 19040  'ERRMSG
  906. 19050  'Prints error & diag msgs
  907. 19060  '=====================
  908. 19070  ERRORFLAG = TRUE
  909. 19080  IF AUDIO THEN BEEP
  910. 19090  IF DIAGFLAG = TRUE THEN DIAG = DIAG + 1: PRINT#2, "****Diagnostic: ";              ELSE ERRS = ERRS + 1: PRINT#2, "****";
  911. 19100  PRINT #2, MSG$;: IF PASS = 1 THEN PRINT#2, " in"; LINENUM ELSE PRINT#2,
  912. 19110  IF L$ = "scrn:" THEN 19140
  913. 19120    IF DIAGFLAG THEN PRINT "****Diagnostic: "; ELSE PRINT "****";
  914. 19130    PRINT MSG$; " in"; LINENUM
  915. 19140  DIAGFLAG = FALSE: RETURN
  916. 19150  '=========
  917. 19160  'FINALPROC
  918. 19170  '=========
  919. 19180  IF STKTOP > 0 THEN MSG$ = "Error: missing ENDP": GOSUB 19030
  920. 19190  PRINT#2,: PRINT#2,: PRINT#2, ERRS; "Error(s) detected"
  921. 19200  XTRA = XTRA + 3: GOSUB 18670 'page eject?
  922. 19210  PRINT#2, DIAG; "Diagnostic(s) offered": XTRA = XTRA + 1: GOSUB 18670
  923. 19220  PRINT#2,: PRINT#2, BYTESGEN;"(";HEX$(BYTESGEN);                                   "H) Bytes of object code generated"
  924. 19230  XTRA = XTRA + 2: GOSUB 18670
  925. 19240  'scrn report
  926. 19250  IF L$ = "scrn:" THEN 19290
  927. 19260    PRINT: PRINT ERRS; "Error(s) detected"
  928. 19270    PRINT DIAG; "Diagnostic(s) offered"
  929. 19280    PRINT: PRINT BYTESGEN;"(";HEX$(BYTESGEN);                                         "H) Bytes of object code generated"
  930. 19290  'dump sym table
  931. 19300   GOSUB 19340
  932. 19310  'reset printer
  933. 19320   IF L$ = "lpt1:" THEN PRINT#2, PMODEOFF$
  934. 19330  RETURN
  935. 19340  '=============
  936. 19350  'DUMP_SYMTABLE
  937. 19360  '=============
  938. 19370  IF NUMSYM = PREDEF THEN RETURN
  939. 19380  PRINT#2,: PRINT#2, "SYMBOL TABLE DUMP:": XTRA = XTRA + 2: GOSUB 18670
  940. 19390  I = PREDEF + 1
  941. 19400  F$ =  "\        \!\  \\  \"  'format
  942. 19410  PERLINE = LWIDTH \ LEN(F$)
  943. 19420  WHILE I <= NUMSYM
  944. 19430    H$ = HEX$(VAL1(I)): H$ = STRING$(4-LEN(H$),"0") + H$
  945. 19440    PRINT#2, USING F$; SYM$(I); " ";  H$; "    ";
  946. 19450    I = I + 1
  947. 19460    IF (I - PREDEF) MOD PERLINE <> 1 THEN 19480
  948. 19470      PRINT#2,: XTRA = XTRA + 1: GOSUB 18670
  949. 19480    WEND
  950. 19490  PRINT#2,: XTRA = XTRA + 1
  951. 19500  RETURN
  952. 19510  '=====
  953. 19520  'EXIT
  954. 19530  '=====
  955. 19540  LOCATE 25,1: BEEP: COLOR BG,FG
  956. 19550  PRINT TAB(30) "Hit any key to exit" TAB(79);
  957. 19560  C$ = INKEY$: IF C$ = "" THEN 19560
  958. 19570  COLOR FG,BG: CLS: SYSTEM
  959. 19580  '==============
  960. 19590  'PROGESS REPORT
  961. 19600  '==============
  962. 19610  X = POS(0): Y = CSRLIN: LOCATE 25,1: COLOR BG,FG
  963. 19620  PRINT "Errors:"; ERRS TAB(16) "<<Esc aborts>>     Pass ";
  964. 19630  IF PASS = 1 THEN PRINT "ONE"; ELSE PRINT "TWO";
  965. 19640  PRINT " in progress.";
  966. 19650  IF PASS = 1 THEN PRINT TAB(69) "Line:"; LINENUM;                                   ELSE PRINT TAB(61) "Line:"; LINENUM; "of"; TOTALINES;
  967. 19660  PRINT TAB(80);: COLOR FG,BG: LOCATE Y,X
  968. 19670  RETURN
  969. 19680  '===========
  970. 19690  'FINISH_INIT
  971. 19700  '===========
  972. 19710  GOSUB 19740 'sym table
  973. 19720  PAGE = 1: GOSUB 19840 'header
  974. 19730  RETURN
  975. 19740  '=================
  976. 19750  'SYM_TABLE
  977. 19760  'Sets up sym table
  978. 19770  '=================
  979. 19780  FOR I = 1 TO PREDEF  'pre-defined
  980. 19790    INPUT#3, SYM$(I), VAL1(I), VAL2(I), SYMTYPE(I)
  981. 19800    NEXT I
  982. 19810  NUMSYM = PREDEF
  983. 19820  CLOSE 3
  984. 19830  RETURN
  985. 19840  '======
  986. 19850  'HEADER
  987. 19860  '======
  988. 19870  'printer set up?
  989. 19880   IF L$ <> "lpt1:" OR PMODEON$ = "" THEN 19910
  990. 19890     PRINT#2, PMODEON$
  991. 19900     WIDTH#2, 132: LWIDTH = 126
  992. 19910  'title & date
  993. 19920   D$ = LEFT$(DATE$,2) + "/" + MID$(DATE$,4,2) + "/" +  RIGHT$(DATE$,2)
  994. 19930   PRINT#2, SC$ TAB(LWIDTH-LEN(D$)) D$
  995. 19940   PRINT#2, "Page:"; PAGE TAB(LWIDTH-LEN(TIME$)) TIME$: PRINT#2,: PRINT#2,
  996. 19950   IF PASS = 2 AND LINENUM = TOTALINES THEN XTRA = XTRA + 6: RETURN
  997. 19960  'column headings
  998. 19970   PRINT#2,"LOC"TAB(6)"OBJ"TAB(19)"LINE"TAB(25)"SOURCE":PRINT#2,
  999. 19980  'used 7 lines
  1000. 19990  XTRA = XTRA + 7
  1001. 20000  RETURN
  1002. 20010  '=====
  1003. 20020  'ABORT
  1004. 20030  '=====
  1005. 20040   C$ = INKEY$: IF C$ <> CHR$(27) THEN RETURN
  1006. 20050   BEEP: PRINT"Assembly aborted from keyboard."
  1007. 20060   GOTO 19510 'exit
  1008. 50000  '====================
  1009. 50010  'INIT
  1010. 50020  'Initializes all but sym table
  1011. 50030  '====================
  1012. 50040  ERRS = 0: DIAG = 0
  1013. 50050  'constants
  1014. 50060   GOSUB 50920
  1015. 50070  'configure
  1016. 50080   GOSUB 50180
  1017. 50090  'expert mode? vers 3 only
  1018. 50100  'gosub 60000: if found then 50150
  1019. 50110  'title page
  1020. 50120   GOSUB 50680
  1021. 50130  'files
  1022. 50140   GOSUB 51080
  1023. 50150  'op table
  1024. 50160   GOSUB 51670
  1025. 50170  RETURN
  1026. 50180  '===============
  1027. 50190  'CONFIG
  1028. 50200  'Reads CHASM.CFG
  1029. 50210  '===============
  1030. 50220  'defaults:
  1031. 50230  PMODEON$ = "": PMODEOFF$ = "": LWIDTH = 79: AUDIO = 1
  1032. 50240  FG = 7: BG = 0: MAXLINES = 58: PAGELEN = 66
  1033. 50250  ON ERROR GOTO 50510
  1034. 50260  OPEN "chasm.cfg" FOR INPUT AS 3
  1035. 50270  '
  1036. 50280  WHILE NOT EOF(3)
  1037. 50290    INPUT#3, C$
  1038. 50300    IF C$ <> "/80" THEN 50320
  1039. 50310      GOSUB 50610: PMODEOFF$ = CTL$: GOTO 50440
  1040. 50320    IF C$ <> "/132" THEN 50340
  1041. 50330      GOSUB 50610: PMODEON$ = CTL$: GOTO 50440
  1042. 50340    IF C$ <> "/LINES" THEN 50360
  1043. 50350      INPUT#3, MAXLINES
  1044. 50360    IF C$ <> "/PAGELEN" THEN 50380
  1045. 50370      INPUT#3, PAGELEN
  1046. 50380    IF C$ <> "/FG" THEN 50400
  1047. 50390      INPUT#3, FG
  1048. 50400    IF C$ <> "/BG" THEN 50420
  1049. 50410      INPUT#3, BG
  1050. 50420    IF C$ <> "/BEEP" THEN 50450
  1051. 50430      INPUT#3, AUDIO
  1052. 50440    IF OVERRAN THEN OVERRAN = FALSE: GOTO 50300
  1053. 50450    WEND
  1054. 50460  CLOSE #3
  1055. 50470  'config screen
  1056. 50480   WIDTH 80: COLOR FG,BG,BG: KEY OFF: CLS
  1057. 50490  ON ERROR GOTO 0
  1058. 50500  RETURN
  1059. 50510  IF ERL = 50260 THEN 50590
  1060. 50520    BEEP: COLOR FG,BG: CLS: COLOR BG,FG: LOCATE 12,25
  1061. 50530    PRINT "Problem with CHASM.CFG"
  1062. 50540    COLOR FG,BG: LOCATE 24,15
  1063. 50550    PRINT "Hit Esc to exit, anything else to continue...";
  1064. 50560    I$ = INKEY$: IF I$ = "" THEN 50560
  1065. 50570    IF I$ = CHR$(27) THEN SYSTEM
  1066. 50580    CLS
  1067. 50590  RESUME 50480
  1068. 50600  '
  1069. 50610  OVERRAN = FALSE: CTL$ = "": INPUT#3, C$
  1070. 50620  WHILE (NOT EOF(3)) AND (LEFT$(C$,1) <> "/")
  1071. 50630    CTL$ = CTL$ + CHR$(VAL(C$))
  1072. 50640    INPUT#3, C$
  1073. 50650    WEND
  1074. 50660  IF EOF(3) THEN CTL$ = CTL$ + CHR$(VAL(C$)) ELSE OVERRAN = TRUE
  1075. 50670  RETURN
  1076. 50680  '=====
  1077. 50690  'TITLE
  1078. 50700  '=====
  1079. 50710  CLS: LOCATE 24,1,0
  1080. 50720  PRINT TAB(12)"KEY";STRING$(56,"THEN");"CLOSE
  1081. 50730  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1082. 50740  PRINT TAB(12)"OPEN"TAB(32)"CHASM  version 2.13"TAB(69)"OPEN
  1083. 50750  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1084. 50760  PRINT TAB(12)"OPEN"TAB(25)"Cheap Assembler for the IBM PC"TAB(69)"OPEN
  1085. 50770  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1086. 50780  PRINT TAB(12)"OPEN      If you have used this program and found it of     OPEN
  1087. 50790  PRINT TAB(12)"OPEN   value, your $30 contribution will be appreciated.    OPEN
  1088. 50800  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1089. 50810  PRINT TAB(12)"OPEN"TAB(29)"David Whitman"TAB(69)"OPEN
  1090. 50820  PRINT TAB(12)"OPEN"TAB(29)"136 Wellington Terrace"TAB(69)"OPEN
  1091. 50830  PRINT TAB(12)"OPEN"TAB(29)"Lansdale, PA  19446"TAB(69)"OPEN
  1092. 50840  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1093. 50850  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1094. 50860  PRINT TAB(12)"OPEN   You are encouraged to copy and share this program.   OPEN
  1095. 50870  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1096. 50880  PRINT TAB(12)"SCREEN";STRING$(56,"THEN");"LOAD":PRINT
  1097. 50890  PRINT TAB(27) "Hit any key to continue...":PRINT:PRINT
  1098. 50900  I$ = INKEY$: IF I$ = "" THEN 50900
  1099. 50910  CLS: RETURN
  1100. 50920  '=========
  1101. 50930  'CONSTANTS
  1102. 50940  '=========
  1103. 50950  'general
  1104. 50960   TRUE = -1: FALSE = 0: DELIM$ = " ,"
  1105. 50970  'flag values
  1106. 50980  'bits 3-5 reserved for ext. values
  1107. 50990   MACHOP = 1: AUTOW = 4: ADDREG = 64: NEEDEXT = 128
  1108. 51000   NEEDISP8 = 256: NEEDISP16 = 512: NEEDMODEBYTE = 1024: NEEDIMMED8 = 2048
  1109. 51010   NEEDIMMED = 4096: DIRECTION = 8192: NEEDMEM = 16384: AUTOC = &H8000
  1110. 51020  'operand types
  1111. 51030   ACUM8 = 1: ACUM16 = 2: REG8 = 4: REG16 = 8: MEMREG = 16: CS = 32
  1112. 51040   SEGR = 64: MEM = 128: IMMED8 = 256: IMMED16 = 512: NONE = 1024
  1113. 51050   STRING = 2048: NEAR = 4096: FAR = 8192: CL = 16384
  1114. 51060  CR$ = "Copyright (c) 1983 by David Whitman"
  1115. 51070  RETURN
  1116. 51080  '======================
  1117. 51090  'OPEN_FILES
  1118. 51100  'Gets & opens i/o files
  1119. 51110  '======================
  1120. 51120  ON ERROR GOTO 51310
  1121. 51130  'input file
  1122. 51140   LOCATE 1,1: INPUT"Source code file name? [.asm] ", S$
  1123. 51150   IF S$ = "" THEN BEEP: GOTO 51140
  1124. 51160   'no ext, add default
  1125. 51170    IF INSTR(S$,".") = 0 THEN SC$ = S$ + ".asm"                                       ELSE SC$ = S$: S$ = LEFT$(S$,INSTR(S$,".")-1)
  1126. 51180   OPEN SC$ FOR INPUT AS #1
  1127. 51190   LOCATE 3,1
  1128. 51200  'listing
  1129. 51210   GOSUB 51510
  1130. 51220  'obj file
  1131. 51230   LOCATE 5,1: PRINT "Name for object file?  [";S$;".com] ";
  1132. 51240   INPUT "",O$
  1133. 51250   'default:
  1134. 51260    IF O$ = "" THEN O$ = S$ + ".com"
  1135. 51270   'open later
  1136. 51280  ON ERROR GOTO 0
  1137. 51290  PRINT: PRINT: PRINT
  1138. 51300  RETURN
  1139. 51310  '=============
  1140. 51320  'Error Handler
  1141. 51330  '=============
  1142. 51340  IF (ERL <> 51180) AND (ERL <> 60360) THEN 51430
  1143. 51350    COLOR BG,FG: BEEP
  1144. 51360    PRINT SC$;" not found.  Press Esc to exit, anything else to continue.";
  1145. 51370    SC$ = INKEY$: IF SC$ = "" THEN 51370
  1146. 51380    LOCATE ,1: COLOR FG,BG: PRINT TAB(80);
  1147. 51390    IF SC$ = CHR$(27) THEN SYSTEM
  1148. 51400    IF ERL = 60360 THEN FOUND = FALSE: RESUME 60600
  1149. 51410    LOCATE 1,31: PRINT TAB(80); : LOCATE ,1: RESUME 51140
  1150. 51420  '
  1151. 51430  IF (ERL <> 51650) AND (ERL <> 60510) THEN 51500
  1152. 51440    CLOSE #2: COLOR BG,FG: BEEP
  1153. 51450    PRINT"Printer not available.  Press any key to continue.";
  1154. 51460    L$ = INKEY$ : IF L$ = "" THEN 51460
  1155. 51470    LOCATE ,1: COLOR FG,BG: PRINT TAB(80);
  1156. 51480    LOCATE Y,63: PRINT TAB(80);: LOCATE ,1
  1157. 51490    IF ERL = 51650 THEN RESUME 51550 ELSE ERRORFLAG = TRUE: RESUME 60520
  1158. 51500  ON ERROR GOTO 0
  1159. 51510  '=========
  1160. 51520  'OPEN LIST
  1161. 51530  '=========
  1162. 51540  Y = CSRLIN
  1163. 51550  INPUT"Direct listing to Printer (P), Screen (S), or Disk (D)? [nul:] ",L$
  1164. 51560  IF L$ = "" THEN L$ = "nul": GOTO 51640 'default is none
  1165. 51570  IF INSTR("PpSsDd",L$) = 0 THEN BEEP: LOCATE Y,63: PRINT TAB(80):                   LOCATE Y,1: GOTO 51550
  1166. 51580  IF L$ = "P" OR L$ = "p" THEN L$ = "lpt1:" : GOTO 51640
  1167. 51590  IF L$ = "S" OR L$ = "s" THEN L$ = "scrn:" : GOTO 51640
  1168. 51600    LOCATE Y,1: PRINT TAB(80);: LOCATE ,1
  1169. 51610    PRINT"Name for listing file? [";S$;".lst] ";
  1170. 51620    INPUT "",L$
  1171. 51630    IF L$ = "" THEN L$ = S$ + ".lst"
  1172. 51640  OPEN L$ FOR OUTPUT AS 2
  1173. 51650  PRINT#2,: XTRA = XTRA + 1 'test printer
  1174. 51660  RETURN
  1175. 51670  '========
  1176. 51680  'OP_TABLE
  1177. 51690  '========
  1178. 51700  X = POS(0): Y = CSRLIN: LOCATE 25,1: COLOR BG+16,FG
  1179. 51710  PRINT TAB(30) "*Set-up in progress*" TAB(80);
  1180. 51720  COLOR FG,BG: LOCATE Y,X
  1181. 51730  OPEN "chasm.dat" FOR INPUT AS 3
  1182. 51740  FOR I = 1 TO NUMOP
  1183. 51750    INPUT#3, OPCODE$(I),OPVAL(I),DSTTYPE(I),SRCTYPE(I),OFLAG(I)
  1184. 51760    NEXT I
  1185. 51770  RETURN
  1186.